import {
  take,
  put,
  fork, // 开启一个子进程来运行 saga ( 简单实现 和 yield 一样 )
  takeEvery,
  call,
  cps,
  all, // 执行所有的迭代器对象后再执行当前 saga
  cancel, // 取消 子 saga 生成器函数 的继续执行
  delay,
} from '../../redux-saga/effects'

// 获取 action 动作对象类型
import * as types from '../action.types'

/**
 * 等待 time 时间后返回一个成功的 promise
 */
// function delay(time) {
//   console.log('delay 函数执行了')
//   return new Promise(resolve => setTimeout(resolve, time))
// }

/**
 * worker saga 用于做具体的事件
 */
function* workerSaga() {
  // yield put({ type: types.ADD }) // 同步 dispatch 派发一个 action


  // yield delay(1000) // 执行 delay 方法
}

/**
 * watcherSaga 用于监听 dispatch 派发动作来决定执行 worker saga
 * 监听 redux 中 dispatch 调用时的 action 派发的动作
 */
function* watcherSaga() {
  // yield take(types.ASYNC_ADD)
  // yield workerSaga() // 然后执行 worker saga

  // 调用 take 产出一个 effect 等待 dispatch 调用时派发一个 types.ASYNCADD 类型的动作
  // 如果没有监听到则 saga 会停在这个地方
  // 如果监听到了就 执行 worker saga
  // while(1)  {
  //   yield take(types.ASYNC_ADD)
  //   yield workerSaga() // 然后执行 worker saga
  // }

  // yield take(types.ASYNC_ADD)
  // 开启一个子进程 来运行 worker saga
  // yield fork(workerSaga)
  // console.log('watcherSaga 生成器函数 执行完毕') // 继续执行当前的 saga
}

function delay2(ms, callback) {
  setTimeout(() => {
    callback()
  }, ms)
}

function delay3(ms, callback) {
  setTimeout(() => {
    callback(null, '回调函数传递的数据')
  }, ms)
}

function* add() {
  // yield call(delay, 1000)
  // yield put({ type: types.ADD })

  let result = yield cps(delay3, 1000 * 5)
  console.log('回调函数返回的数据', result)
  yield put({ type: types.ADD })
  console.log('add saga 生成器')
}


function* add2() {
  for (let i = 0; i < 1; i++) {
    yield take(types.ASYNC_ADD) // 监听动作
    yield put({ type: types.ADD }) // 派发动作
  }
  console.log('add2 saga 结束了')
  return 'add2 result'
}

function* add3() {
  for (let i = 0; i < 2; i++) {
    yield take(types.ASYNC_ADD) // 监听动作
    yield put({ type: types.ADD }) // 派发动作
  }
  console.log('add3 saga 结束了')
  return 'add3 result'
}

function* add4() {
  while (true) {
    yield delay(1000) // 使用 effects 内置的 delay 方法来延迟
    yield put({ type: types.ADD }) // 派发一个 { type: "ADD" } 动作
  }
}

function* addWatcher() {
  const task = yield fork(add4) // 开启一个子进程执行 add4 生成器函数 并获取 fork 返回的任务
  yield take(types.STOP_ADD) // 监听 dispatch 派发的 { type: 'STOP_ADD' } 动作
  yield cancel(task) // 取消 fork 返回的任务
}

/**
 * 根 saga\
 * 内部会使用 watcherSaga 监听 dispatch 派发的动作
 */
function* rootSaga() {
  // yield watcherSaga()

  // yield takeEvery(types.ASYNC_ADD, add)

  // let result = yield all([add2(), add3()]) // 执行所有的迭代器后才会执行当前 saga 生成器
  // console.log('执行完了所有的迭代器', result)

  // yield addWatcher() // 执行一个子 saga 生成器函数
  // console.log('rootSaga next')

  yield add()
  console.log('rootSaga end')
}

export default rootSaga
